package com.kgc.student.studentservice.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.github.pagehelper.PageInfo;
import com.kgc.student.entity.Studentinfo;
import com.kgc.student.service.StudentinfoService;
import com.kgc.student.studentservice.mapper.StudentinfoMapper;
import com.kgc.student.util.RedisUtil;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;


@Service
@Component
public class StudentServiceImpl implements StudentinfoService {
    @Resource
    StudentinfoMapper studentinfoMapper;
    @Resource
    RedisUtil redisUtil;
    @Override
    public List<Studentinfo> selectAll() {
        List<Studentinfo> studentinfos = studentinfoMapper.selectList(null);
        return studentinfos;
    }

    @Override
    public Studentinfo selectById(Integer id) {
        Studentinfo studentinfo=null;
        Jedis jedis = redisUtil.getJedis();
        String key= "stu:"+id;
        String stuJson = jedis.get(key);
        if (stuJson!=null){
            //解决缓存穿透
            if (stuJson.equals("empty")){
                return null;
            }
            //从redis查询数据
             studentinfo= JSON.parseObject(stuJson, Studentinfo.class);
            jedis.close();
        }else {
            //使用nx分布式锁，避免缓存击穿
            String skuLockKey="stuId"+id;
            String skuLockValue= UUID.randomUUID().toString();
            String lockKey=jedis.set(skuLockKey,skuLockValue,"NX","PX",60*1000);
            if (lockKey.equals("OK")){
                //从数据库查数据
                studentinfo = studentinfoMapper.selectById(id);
                //解决缓存穿透防止雪崩
                if (studentinfo!=null){
                    //保存到redis
                    String string = JSON.toJSONString(studentinfo);
                    //有效生成随机的时间
                    Random random=new Random();
                    int nextInt = random.nextInt(10);
                    jedis.setex(key,nextInt*60*1000,string);
                }else {
                    jedis.setex(key,5*60*1000,"empty");
                }
                String script ="if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
                jedis.eval(script, Collections.singletonList(skuLockKey),Collections.singletonList(skuLockValue));
            }else {
                //如果分布式锁访问失败，线程休眠3秒，重新访问
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            }
            return  studentinfo;
        }



    @Override
    public Integer updateStudent(Studentinfo studentinfo) {
        int i = studentinfoMapper.updateById(studentinfo);
        return i;
    }

    @Override
    public boolean saveBatch(Collection<Studentinfo> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdateBatch(Collection<Studentinfo> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean updateBatchById(Collection<Studentinfo> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdate(Studentinfo entity) {
        return false;
    }

    @Override
    public Studentinfo getOne(Wrapper<Studentinfo> queryWrapper, boolean throwEx) {
        return null;
    }

    @Override
    public Map<String, Object> getMap(Wrapper<Studentinfo> queryWrapper) {
        return null;
    }

    @Override
    public <V> V getObj(Wrapper<Studentinfo> queryWrapper, Function<? super Object, V> mapper) {
        return null;
    }

    @Override
    public BaseMapper<Studentinfo> getBaseMapper() {
        return null;
    }
}
